package com.alibaba.citrus.cr.sales.plan.facade.service.salesplan.audit;

import com.alibaba.citrus.cr.common.annotation.EpochTransactional;
import com.alibaba.citrus.cr.common.annotation.FacadeInvoker;
import com.alibaba.citrus.cr.common.exception.FacadeException;
import com.alibaba.citrus.cr.sales.plan.dto.api.request.SalesPlanReportRequest;
import com.alibaba.citrus.cr.sales.plan.model.SalesPlanReportStatusEnum;
import com.alibaba.citrus.cr.sales.plan.model.enums.SalesPlanModelEnum;
import com.alibaba.citrus.cr.sales.plan.repository.PlatformEnhanceRepository;
import com.alibaba.citrus.cr.sales.plan.repository.request.OrganizationListQueryRequest;
import com.alibaba.cz.base.tool.log.Log;
import com.alibaba.cz.base.tool.message.ErrorMessage;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.lattice2.epoch.sdk.model.Result;
import com.epoch.app.bcorder.auditsetting.dto.Load1Request;
import com.epoch.app.bcorder.auditsetting.model.AuditSetting;
import com.epoch.app.bcorder.auditsetting.service.AuditSettingService;
import com.epoch.app.bcorder.auditsettingdetail.dto.*;
import com.epoch.app.bcorder.auditsettingdetail.model.AuditSettingDetail;
import com.epoch.app.bcorder.model.dto.*;
import com.epoch.app.bcorder.auditsettingdetail.service.AuditSettingDetailService;
import com.epoch.app.bcorder.model.enums.AuditSettingStatusEnum;
import com.epoch.app.bcorder.model.enums.AuditSettingTypeEnum;
import com.epoch.app.bcorder.sales_plan.salesplanreport.model.SalesPlanReport;
import com.epoch.app.bcorder.sales_plan.salesplanreport.service.SalesPlanReportService;
import com.epoch.app.bcorder.service.BaseDataService;
import com.epoch.app.bcorder.service.BcOrderService;
import com.epoch.app.crplatformenhance.enums.OrganizationTypeEnum;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Component
public class AuditSettingDetailServiceImpl implements AuditSettingDetailService {

    private final Log log = Log.getLogger(AuditSettingDetailServiceImpl.class);

    @Resource
    private BcOrderService bcOrderService;

    @Resource
    private BaseDataService baseDataService;

    @Resource(name = "auditSettingServiceImpl")
    private AuditSettingService auditSettingService;

    @Resource
    private SalesPlanReportService salesPlanReportService;

    @Resource
    private PlatformEnhanceRepository platformEnhanceRepository;

    private static final int ZERO = 0;
    private static final int ONE = 1;

    @Override
    public Result<List<AuditSettingDetailResponse>> pageQueryAuditSettingDetail(PageQueryAuditSettingDetailRequest pageQueryAuditSettingDetailRequest) {
        log.info("AuditSettingDetailService.pageQueryAuditSetting.request={}", JSONObject.toJSONString(pageQueryAuditSettingDetailRequest));
        if (null == pageQueryAuditSettingDetailRequest.getAuditSettingId()) {
            return Result.fail("OTS-02-003-01-15-010", ErrorMessage.code("OTS-02-003-01-15-010", null).getDisplayErrorMessage());
        }
        AuditSettingDetailLoadListRequest request = convertRequest(pageQueryAuditSettingDetailRequest);
        Result<List<AuditSettingDetail>> result = loadList(request);
        if (!result.isSuccess()) {
            return Result.fail("OTS-02-003-01-16-028", ErrorMessage.code("OTS-02-003-01-16-028", null).getDisplayErrorMessage());
        }
        log.info("AuditSettingDetailService.loadList.result={}", JSONObject.toJSONString(result));
        return Result.listSuccess(convertResponseList(result.getResult()), result.getTotal());
    }

    @Override
    public Result<String> createAuditSettingDetail(CreateAuditSettingDetailRequest createAuditSettingDetailRequest) {
        log.info("AuditSettingDetailService.createAuditSettingDetail.request={}", JSONObject.toJSONString(createAuditSettingDetailRequest));
        if (StringUtils.isEmpty(createAuditSettingDetailRequest.getOrganizationType())) {
            return Result.fail("OTS-02-003-01-15-012", ErrorMessage.code("OTS-02-003-01-15-012", null).getDisplayErrorMessage());
        }
        if (StringUtils.isEmpty(createAuditSettingDetailRequest.getRoleId())) {
            return Result.fail("OTS-02-003-01-15-013", ErrorMessage.code("OTS-02-003-01-15-013", null).getDisplayErrorMessage());
        }
        if (null == createAuditSettingDetailRequest.getAuditSettingId()) {
            return Result.fail("OTS-02-003-01-15-010", ErrorMessage.code("OTS-02-003-01-15-010", null).getDisplayErrorMessage());
        }

        Result<String> checkCreate = checkCreate(createAuditSettingDetailRequest);

        if (!checkCreate.isSuccess()) {
            return checkCreate;
        }
        //判断是否有重复审批节点
        Result<List<AuditSettingDetail>> resultList = checkRepeatDetail(createAuditSettingDetailRequest.getAuditSettingId(), 
                createAuditSettingDetailRequest.getOrganizationType(), createAuditSettingDetailRequest.getRoleId());
        if (!resultList.isSuccess()) {
            return Result.fail(resultList.getErrorCode(), resultList.getMessage());
        }
        EmployeeGetCurrentLoginResponse loginResponse = bcOrderService.employeeGetCurrentLogin();
        if (!loginResponse.getSuccess()) {
            log.info("获取登录人信息失败AuditSettingDetailService.createAuditSettingDetail.employeeGetCurrentLoginResponse={}", JSONObject.toJSONString(loginResponse));
        }
        AuditSettingDetail auditSettingDetail = new AuditSettingDetail();
        auditSettingDetail.setOrganizationType(createAuditSettingDetailRequest.getOrganizationType());
        auditSettingDetail.setRoleId(createAuditSettingDetailRequest.getRoleId());
        auditSettingDetail.setAuditSettingId(createAuditSettingDetailRequest.getAuditSettingId());
        auditSettingDetail.setAuditSequence(resultList.getResult() == null ? ONE : resultList.getResult().size() + ONE);
        auditSettingDetail.setStatus(AuditSettingStatusEnum.ENABLE.getType());
        auditSettingDetail.setGmtCreate(new Date());
        auditSettingDetail.setGmtModified(new Date());
        auditSettingDetail.setCreator(loginResponse.getEmployeeId());
        auditSettingDetail.setUpdater(loginResponse.getEmployeeId());
        auditSettingDetail.setVersion(ZERO);
        CreateResponse response = null;
        try {
            response = create(auditSettingDetail);
        } catch (Exception e) {
            log.info("审批配置详情创建失败={}", e);
            return Result.fail("OTS-02-003-01-16-029", ErrorMessage.code("OTS-02-003-01-16-029", null).getDisplayErrorMessage());
        }
        return Result.success(response.getId());
    }

    @EpochTransactional(appCode = "bc_order", dataSourceCode = "cr_ots", dataSourceType = "app")
    @Override
    public Result<Boolean> deleteAuditSettingDetail(DeleteAuditSettingDetailRequest deleteAuditSettingDetailRequest) {
        log.info("AuditSettingDetailService.deleteAuditSettingDetail.request={}", JSONObject.toJSONString(deleteAuditSettingDetailRequest));
        if (null == deleteAuditSettingDetailRequest.getId()) {
            return Result.fail("OTS-02-003-01-15-014", ErrorMessage.code("OTS-02-003-01-15-014", null).getDisplayErrorMessage());
        }
        try {
            AuditSettingDetail auditSettingDetail = load(LoadRequest.builder().id(deleteAuditSettingDetailRequest.getId()).build());
            if (null == auditSettingDetail) {
                return Result.fail("OTS-02-003-01-16-030", ErrorMessage.code("OTS-02-003-01-16-030", null).getDisplayErrorMessage());
            }
            //删除校验
            Result<Boolean> checkResult = check(auditSettingDetail);
            if (!checkResult.isSuccess()) {
                return checkResult;
            } else if (!checkResult.getResult()) {
                return Result.fail("OTS-02-003-01-16-040", ErrorMessage.code("OTS-02-003-01-16-040", null).getDisplayErrorMessage());
            }
            //删除审批节点
            DeleteResponse deleteResponse = delete(DeleteRequest.builder().id(deleteAuditSettingDetailRequest.getId()).build());
            if (deleteResponse.getCount() != ONE) {
                return Result.fail("OTS-02-003-01-16-031", ErrorMessage.code("OTS-02-003-01-16-031", null).getDisplayErrorMessage());
            }
            //判断删除的节点是不是最后一个，如果不是就重新排列审批顺序
            Result<Boolean> result = updateAuditSequence(auditSettingDetail);
            return result.isSuccess() ? Result.success(true) : Result.success(false, result.getErrorCode(), result.getMessage());
        } catch (Exception e) {
            log.info("审批配置详情删除失败={}", e);
            return Result.fail("OTS-02-003-01-16-031", ErrorMessage.code("OTS-02-003-01-16-031", null).getDisplayErrorMessage());
        }
    }

    @Override
    @FacadeInvoker
    public Result<Boolean> updateAuditSettingDetail(UpdateAuditSettingDetailRequest updateAuditSettingDetailRequest) {
        log.info("AuditSettingDetailService.updateAuditSettingDetail.request={}", JSONObject.toJSONString(updateAuditSettingDetailRequest));
        if (null == updateAuditSettingDetailRequest.getId()) {
            return Result.fail("OTS-02-003-01-15-014", ErrorMessage.code("OTS-02-003-01-15-014", null).getDisplayErrorMessage());
        }
        try {
            AuditSettingDetail auditSettingDetail = load(LoadRequest.builder().id(updateAuditSettingDetailRequest.getId()).build());
            if (null == auditSettingDetail) {
                return Result.fail("OTS-02-003-01-16-032", ErrorMessage.code("OTS-02-003-01-16-032", null).getDisplayErrorMessage());
            }
            //判断是否有重复审批节点
            Result<List<AuditSettingDetail>> resultList = checkRepeatDetail(updateAuditSettingDetailRequest.getAuditSettingId(),
                    updateAuditSettingDetailRequest.getOrganizationType(), updateAuditSettingDetailRequest.getRoleId());
            if (!resultList.isSuccess()) {
                return Result.fail(resultList.getErrorCode(), resultList.getMessage());
            }
            //更新校验
            Result<Boolean> checkResult = check(auditSettingDetail);
            if (!checkResult.isSuccess()) {
                return checkResult;
            } else if (!checkResult.getResult()) {
                return Result.fail("OTS-02-003-01-16-041", ErrorMessage.code("OTS-02-003-01-16-041", null).getDisplayErrorMessage());
            }
            //更新审批节点
            if (StringUtils.isNotEmpty(updateAuditSettingDetailRequest.getOrganizationType())) {
                auditSettingDetail.setOrganizationType(updateAuditSettingDetailRequest.getOrganizationType());
            }
            if (StringUtils.isNotEmpty(updateAuditSettingDetailRequest.getRoleId())) {
                auditSettingDetail.setRoleId(updateAuditSettingDetailRequest.getRoleId());
            }
            auditSettingDetail.setVersion(auditSettingDetail.getVersion() + ONE);
            UpdateResponse updateResponse = update(auditSettingDetail);
            if (updateResponse.getCount() != ONE) {
                return Result.fail("OTS-02-003-01-16-033", ErrorMessage.code("OTS-02-003-01-16-033", null).getDisplayErrorMessage());
            }
            return Result.success(true);
        } catch (Exception e) {
            log.info("审批配置详情修改失败={}", e);
            return Result.fail("OTS-02-003-01-16-033", ErrorMessage.code("OTS-02-003-01-16-033", null).getDisplayErrorMessage());
        }
    }

    @Override
    public Result<String> queryAuditSettingDetailByCurrentLogin(QueryAuditSettingDetailByCurrentLoginRequest queryAuditSettingDetailByCurrentLoginRequest) {
        EmployeeGetCurrentLoginResponse loginResponse = bcOrderService.employeeGetCurrentLogin();
        if (!loginResponse.getSuccess()) {
            log.info("获取登录人信息失败AuditSettingDetailService.queryAuditSettingDetailByCurrentLogin.employeeGetCurrentLoginResponse={}", JSONObject.toJSONString(loginResponse));
            throw new FacadeException("获取登录人信息失败");
        }
        log.info("AuditSettingDetailService.queryAuditSettingDetailByCurrentLogin.loginResponse=" + JSONObject.toJSONString(loginResponse));
        List<String> roleCodes = Lists.newArrayList();
        try {
            String[] roleList = loginResponse.getRoleCodes().replace("[", "").replace("]", "")
                    .replace("\"","").split(",");
            for (String s : roleList) {
                s = s.trim();
                roleCodes.add(s);
            }
        } catch (Exception e) {
            log.info("AuditSettingDetailService.queryAuditSettingDetailByCurrentLogin.转换角色失败={}", e);
            throw new FacadeException("角色信息转换失败");
        }
        if (org.apache.commons.collections.CollectionUtils.isEmpty(roleCodes)) {
            throw new FacadeException(ErrorMessage.code("OTS-02-002-01-15-006", "提报人角色不能为空"));
        }
        log.info("AuditSettingDetailService.queryAuditSettingDetailByCurrentLogin.roleCodes=" + JSONObject.toJSONString(roleCodes));
        Integer organizationType = Integer.valueOf(loginResponse.getRelatedOrganizationType());
        String organizationId = loginResponse.getRelatedOrganizationId();
        List<AuditSetting> auditSettings = getAuditConfiguration(organizationType, organizationId, queryAuditSettingDetailByCurrentLoginRequest.getModel());
        Map</*code*/String, /*id*/String> roleSDOMap = getRoleSDOMap2();
        // 校验提报配置,获取提报人能够审批的节点
        for (AuditSetting auditSetting : auditSettings) {
            String text = checkReportSetting(auditSetting, roleSDOMap, organizationType, roleCodes);
            if (StringUtils.isNotEmpty(text)) {
                return Result.success(text);
            }
        }
        return Result.success("");
    }

    private List<AuditSettingDetailResponse> convertResponseList(List<AuditSettingDetail> auditSettingDetailList) {
        //获取角色信息
        Map<String, String> roleSDOMap = getRoleSDOMap();
        //查询员工
        Set<String> employeeIds = auditSettingDetailList.stream().map(AuditSettingDetail::getCreator).collect(Collectors.toSet());
        employeeIds.addAll(auditSettingDetailList.stream().map(AuditSettingDetail::getUpdater).collect(Collectors.toSet()));
        Map<String, String> employeeSDOMap = getEmployeeSDOMap(employeeIds);
        Map<String, String> organizationTypeMap = Arrays.stream(OrganizationTypeEnum.values()).collect(Collectors.toMap(x -> x.getCode().toString(), OrganizationTypeEnum::getDesc));
        List<AuditSettingDetailResponse> list = new ArrayList<>();
        for (AuditSettingDetail auditSettingDetail : auditSettingDetailList) {
            list.add(convertResponse(roleSDOMap, employeeSDOMap, organizationTypeMap, auditSettingDetail));
        }
        return list;
    }

    private Map<String, String> getEmployeeSDOMap(Set<String> employeeIds) {
        Map<String, String> employeeSDOMap = new HashMap<>();
        Result<List<EmployeeSDO>> employeeResult = baseDataService.baselineGetEmployeeByIdsAll(BaselineGetEmployeeByIdsAllRequest.builder()
                .ids(new ArrayList<String>(employeeIds)).build());
        if (!employeeResult.isSuccess() || CollectionUtils.isEmpty(employeeResult.getResult())) {
            log.info("查询员工信息失败AuditSettingDetailService.convertResponseList.employeeIds={}", JSONObject.toJSONString(employeeIds));
        } else {
            employeeSDOMap = employeeResult.getResult().stream().collect(Collectors.toMap(EmployeeSDO::getId, EmployeeSDO::getName, (a, b) -> a));
        }
        return employeeSDOMap;
    }

    private Map</*id*/String, /*name*/String> getRoleSDOMap() {
        Map<String, String> roleSDOMap = new HashMap<>();
        Result<List<RoleSDO>> result = bcOrderService.getAllRoles(GetAllRolesRequest.builder().belongOrganizationId("1").build());
        if (!result.isSuccess() || CollectionUtils.isEmpty(result.getResult())) {
            log.info("查询角色信息失败AuditSettingDetailService.convertResponseList");
        } else {
            roleSDOMap = result.getResult().stream().collect(Collectors.toMap(RoleSDO::getId, RoleSDO::getName, (a, b) -> a));
        }
        return roleSDOMap;
    }

    private Map</*code*/String, /*id*/String> getRoleSDOMap2() {
        Map<String, String> roleSDOMap = new HashMap<>();
        Result<List<RoleSDO>> result = bcOrderService.getAllRoles(GetAllRolesRequest.builder().belongOrganizationId("1").build());
        if (!result.isSuccess() || org.apache.commons.collections4.CollectionUtils.isEmpty(result.getResult())) {
            log.info("查询角色信息失败AuditSettingDetailService.convertResponseList");
        } else {
            roleSDOMap = result.getResult().stream().collect(Collectors.toMap(RoleSDO::getCode, RoleSDO::getId, (a, b) -> a));
        }
        return roleSDOMap;
    }

    private AuditSettingDetailResponse convertResponse(Map<String, String> roleSDOMap, Map<String, String> employeeSDOMap, Map<String, String> organizationTypeMap, AuditSettingDetail auditSettingDetail) {
        AuditSettingDetailResponse response = new AuditSettingDetailResponse();
        response.setId(auditSettingDetail.getId());
        response.setAuditSettingId(auditSettingDetail.getAuditSettingId());
        response.setAuditSequence(auditSettingDetail.getAuditSequence());
        response.setOrganizationType(auditSettingDetail.getOrganizationType());
        response.setOrganizationTypeName(organizationTypeMap.get(auditSettingDetail.getOrganizationType()));
        response.setParentType(auditSettingDetail.getParentType());
        response.setParentTypeName(organizationTypeMap.get(auditSettingDetail.getParentType()));
        response.setRoleId(auditSettingDetail.getRoleId());
        response.setRoleName(roleSDOMap.get(auditSettingDetail.getRoleId()));
        response.setStatus(auditSettingDetail.getStatus());
        if (null != AuditSettingStatusEnum.of(auditSettingDetail.getStatus())) {
            response.setStatusDesc(AuditSettingStatusEnum.of(auditSettingDetail.getStatus()).getDesc());
        }
        response.setGmtCreate(auditSettingDetail.getGmtCreate());
        response.setGmtModified(auditSettingDetail.getGmtModified());
        response.setCreator(auditSettingDetail.getCreator());
        response.setCreatorName(employeeSDOMap.get(auditSettingDetail.getCreator()));
        response.setUpdater(auditSettingDetail.getUpdater());
        response.setUpdaterName(employeeSDOMap.get(auditSettingDetail.getUpdater()));
        response.setVersion(auditSettingDetail.getVersion());
        return response;
    }

    private AuditSettingDetailLoadListRequest convertRequest(PageQueryAuditSettingDetailRequest pageQueryAuditSettingDetailRequest) {
        AuditSettingDetailLoadListRequest request = AuditSettingDetailLoadListRequest.newAuditSettingDetailLoadListRequestBuilder().build();
        request.setAuditSettingId(pageQueryAuditSettingDetailRequest.getAuditSettingId());
        request.setStart(pageQueryAuditSettingDetailRequest.getStart());
        request.setLimit(pageQueryAuditSettingDetailRequest.getLimit());
        request.setPage(pageQueryAuditSettingDetailRequest.getPage());
        request.setSize(pageQueryAuditSettingDetailRequest.getSize());
        request.setAsc(true);
        return request;
    }

    private Result<List<AuditSettingDetail>> checkRepeatDetail(Long auditSettingId, String organizationType, String roleId) {
        if (null == auditSettingId) {
            return Result.fail("OTS-02-003-01-15-010", ErrorMessage.code("OTS-02-003-01-15-010", null).getDisplayErrorMessage());
        }
        Result<List<AuditSettingDetail>> resultList = loadList(AuditSettingDetailLoadListRequest.newAuditSettingDetailLoadListRequestBuilder()
                .auditSettingId(auditSettingId).build());
        if (!resultList.isSuccess()) {
            return Result.fail("OTS-02-003-01-16-028", ErrorMessage.code("OTS-02-003-01-16-028", null).getDisplayErrorMessage());
        }
        if (CollectionUtils.isNotEmpty(resultList.getResult())) {
            List<AuditSettingDetail> list = resultList.getResult().stream().filter(x ->
                    x.getOrganizationType().equals(organizationType) && x.getRoleId().equals(roleId))
                    .collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(list)) {
                return Result.fail("OTS-02-003-01-16-034", ErrorMessage.code("OTS-02-003-01-16-034", null).getDisplayErrorMessage());
            }
        }
        return resultList;
    }

    private Result<Boolean> updateAuditSequence(AuditSettingDetail auditSettingDetail) {
        log.info("AuditSettingDetailService.updateAuditSequence.request={}", JSONObject.toJSONString(auditSettingDetail));
        Result<List<AuditSettingDetail>> result = loadList(AuditSettingDetailLoadListRequest.newAuditSettingDetailLoadListRequestBuilder()
                .auditSettingId(auditSettingDetail.getAuditSettingId()).sequence(auditSettingDetail.getAuditSequence()).build());
        if (!result.isSuccess()) {
            return Result.fail("OTS-02-003-01-16-036", ErrorMessage.code("OTS-02-003-01-16-036", null).getDisplayErrorMessage());
        }
        if (CollectionUtils.isNotEmpty(result.getResult())) {
            result.getResult().forEach(x -> {
                try {
                    x.setAuditSequence(x.getAuditSequence() - ONE);
                    UpdateResponse updateResponse = update(x);
                    if (updateResponse.getCount() != ONE) {
                        log.info("AuditSettingDetailService更新审批顺序失败,审批节点id={}", x.getId());
                        throw new FacadeException(ErrorMessage.code("OTS-02-003-01-16-036"));
                    }
                } catch (Exception e) {
                    log.info("AuditSettingDetailService更新审批顺序失败={}", e);
                }
            });
        }
        return Result.success(true);
    }

    /**
     * 校验能否删除或修改
     * @param auditSettingDetail
     * @return
     */
    private Result<Boolean> check(AuditSettingDetail auditSettingDetail) {
        AuditSetting auditSetting = auditSettingService.load1(Load1Request.builder().id(auditSettingDetail.getAuditSettingId()).build());
        if (null == auditSetting) {
            return Result.fail(false, "OTS-02-003-01-16-023", ErrorMessage.code("OTS-02-003-01-16-023", null).getDisplayErrorMessage());
        }
        if (StringUtils.isEmpty(auditSetting.getOrgBusinessUnitCode())) {
            return Result.fail("OTS-02-003-01-15-008", ErrorMessage.code("OTS-02-003-01-15-008", null).getDisplayErrorMessage());
        }
        if (StringUtils.isEmpty(auditSetting.getType())) {
            return Result.fail("OTS-02-003-01-15-009", ErrorMessage.code("OTS-02-003-01-15-009", null).getDisplayErrorMessage());
        }
        if (StringUtils.isEmpty(auditSetting.getOrgChannelCode())) {
            return Result.fail("OTS-02-003-01-15-016", ErrorMessage.code("OTS-02-003-01-15-016", null).getDisplayErrorMessage());
        }

        //获取审批配置业务单元下的销售组织
        OrganizationListQueryRequest orgQueryReq = new OrganizationListQueryRequest();
        orgQueryReq.setId(auditSetting.getOrgBusinessUnitCode());
        orgQueryReq.setType(OrganizationTypeEnum.SALES_ORGANIZATION.getCode());
        List<com.epoch.app.crplatformenhance.sdo.OrganizationSDO> orgSaleOrgList = platformEnhanceRepository.getDownOrganizationList(orgQueryReq);
        if (CollectionUtils.isEmpty(orgSaleOrgList)) {
            return Result.fail(false, "OTS-02-003-01-16-038", ErrorMessage.code("OTS-02-003-01-16-038", null).getDisplayErrorMessage());
        }
        List<String> orgSaleOrgIds = orgSaleOrgList.stream().map(com.epoch.app.crplatformenhance.sdo.OrganizationSDO::getId).collect(Collectors.toList());
        //获取审批配置销售渠道下的销售部门
        orgQueryReq.setId(auditSetting.getOrgChannelCode());
        orgQueryReq.setType(OrganizationTypeEnum.SALES_DEPARTMENT.getCode());
        List<com.epoch.app.crplatformenhance.sdo.OrganizationSDO> orgDepartmentList = platformEnhanceRepository.getDownOrganizationList(orgQueryReq);
        if (CollectionUtils.isEmpty(orgDepartmentList)) {
            return Result.fail(false, "OTS-02-003-01-16-038", ErrorMessage.code("OTS-02-003-01-16-038", null).getDisplayErrorMessage());
        }
        List<String> orgDepartmentIds = orgDepartmentList.stream().map(com.epoch.app.crplatformenhance.sdo.OrganizationSDO::getId).collect(Collectors.toList());

        //根据部门id查询员工，获取业务员员工id
        List<EmployeeSDO> list = new ArrayList<>();
        for (String id : orgDepartmentIds) {
            Result<List<EmployeeSDO>> employeeResult = baseDataService.baselineGetEmployeesByRelationOrgId2(BaselineGetEmployeesByRelationOrgId2Request.builder().id(id).build());
            if (!employeeResult.isSuccess() || CollectionUtils.isEmpty(employeeResult.getResult())) {
                log.info("AuditSettingDetailServiceImpl.check查询部门下业务员失败,部门id={}", id);
                continue;
            }
            list.addAll(employeeResult.getResult());
        }
        //根据bizId(组织id+业务员id)和状态查询未完成的提报单
        if (CollectionUtils.isEmpty(list)) {
            return Result.fail(false, "OTS-02-003-01-16-042", ErrorMessage.code("OTS-02-003-01-16-042", null).getDisplayErrorMessage());
        }
        List<String> bizIdList = list.stream().map(EmployeeSDO::getId).collect(Collectors.toList());
        //bizIdList.addAll(organizationList.stream().map(OrganizationSDO::getId).collect(Collectors.toList()));
        bizIdList.add(auditSetting.getOrgBusinessUnitCode());
        bizIdList.addAll(orgSaleOrgIds);
        bizIdList.add(auditSetting.getOrgChannelCode());
        bizIdList.addAll(orgDepartmentIds);

        List<Integer> statusList = Lists.newArrayList(SalesPlanReportStatusEnum.TO_REPORT.getCode(), SalesPlanReportStatusEnum.REPORTED.getCode());
        log.info("AuditSettingDetailServiceImpl.check.bizIdList={}",JSONObject.toJSONString(bizIdList));
        Result<List<SalesPlanReport>> reportResult = null;
        try {
            reportResult = salesPlanReportService.loadSalesPlanReportList(SalesPlanReportLoadListRequest.newSalesPlanReportLoadListRequestBuilder()
                    .bizIdList(bizIdList).statusList(statusList).model(Integer.parseInt(auditSetting.getType())).build());
            log.info("AuditSettingDetailServiceImpl_check_reportResult={}",JSONObject.toJSONString(reportResult));
        } catch (Exception e) {
            log.info("AuditSettingDetailServiceImpl.check查询提报单信息失败={}", e);
            return Result.fail(false, "OTS-02-003-01-16-039", ErrorMessage.code("OTS-02-003-01-16-039", null).getDisplayErrorMessage());
        }
        return CollectionUtils.isEmpty(reportResult.getResult()) ? Result.success(true) : Result.success(false);
    }

    /**
     * 校验能否创建
     * @param auditSettingDetail
     * @return
     */
    private Result<String> checkCreate(CreateAuditSettingDetailRequest auditSettingDetail) {
        AuditSetting auditSetting = auditSettingService.load1(Load1Request.builder().id(auditSettingDetail.getAuditSettingId()).build());
        if (null == auditSetting) {
            return Result.fail("false", "OTS-02-003-01-16-023", ErrorMessage.code("OTS-02-003-01-16-023", null).getDisplayErrorMessage());
        }
        if (StringUtils.isEmpty(auditSetting.getOrgBusinessUnitCode())) {
            return Result.fail("OTS-02-003-01-15-008", ErrorMessage.code("OTS-02-003-01-15-008", null).getDisplayErrorMessage());
        }
        if (StringUtils.isEmpty(auditSetting.getType())) {
            return Result.fail("OTS-02-003-01-15-009", ErrorMessage.code("OTS-02-003-01-15-009", null).getDisplayErrorMessage());
        }
        if (StringUtils.isEmpty(auditSetting.getOrgChannelCode())) {
            return Result.fail("OTS-02-003-01-15-016", ErrorMessage.code("OTS-02-003-01-15-016", null).getDisplayErrorMessage());
        }

        //获取审批配置销售渠道下的销售部门
        OrganizationListQueryRequest orgQueryReq = new OrganizationListQueryRequest();
        orgQueryReq.setId(auditSetting.getOrgChannelCode());
        orgQueryReq.setType(OrganizationTypeEnum.SALES_DEPARTMENT.getCode());
        List<com.epoch.app.crplatformenhance.sdo.OrganizationSDO> orgDepartmentList = platformEnhanceRepository.getDownOrganizationList(orgQueryReq);
        if (CollectionUtils.isEmpty(orgDepartmentList)) {
            return Result.fail("false", "OTS-02-003-01-16-038", ErrorMessage.code("OTS-02-003-01-16-038", null).getDisplayErrorMessage());
        }
        List<String> orgDepartmentIds = orgDepartmentList.stream().map(com.epoch.app.crplatformenhance.sdo.OrganizationSDO::getId).collect(Collectors.toList());

        //根据部门id查询员工，获取业务员员工id
        List<EmployeeSDO> list = new ArrayList<>();
        for (String id : orgDepartmentIds) {
            Result<List<EmployeeSDO>> employeeResult = baseDataService.baselineGetEmployeesByRelationOrgId2(BaselineGetEmployeesByRelationOrgId2Request.builder().id(id).build());
            if (!employeeResult.isSuccess() || CollectionUtils.isEmpty(employeeResult.getResult())) {
                log.info("AuditSettingDetailServiceImpl.check查询部门下业务员失败,部门id={}", id);
                continue;
            }
            list.addAll(employeeResult.getResult());
        }
        //根据bizId(组织id+业务员id)
        if (CollectionUtils.isEmpty(list)) {
            return Result.fail("false", "OTS-02-003-01-16-042", ErrorMessage.code("OTS-02-003-01-16-042", null).getDisplayErrorMessage());
        }

        return Result.success("true") ;
    }

    /**
     * 检查提报配置,获取提报人能够审批的节点
     * @return boolean
     */
    private String checkReportSetting(AuditSetting audit, Map</*code*/String, /*id*/String> roleSDOMap, Integer OrganizationType, List<String> roleCodes) {
        StringBuilder stringBuilder = new StringBuilder();
        List<AuditSettingDetail> auditDetails = obtainAuditSettingDetail(audit);
        log.error("AuditSettingDetailService.auditDetails={}", JSONObject.toJSONString(auditDetails));
        if (org.apache.commons.collections.CollectionUtils.isEmpty(auditDetails)) {
            log.error("AuditSettingDetailService.checkReportSetting当前审批主单id={}, settingDetail={}", audit.getId(),
                    JSONObject.toJSONString(audit));
            throw new FacadeException(ErrorMessage.code("OTS-02-002-01-16-025"));
        }
        Map<String, AuditSettingDetail> detailMap = Maps.newHashMap();
        // 记录最后一个审批节点
        AuditSettingDetail lastAudit = null;
        for (AuditSettingDetail auditDetail : auditDetails) {
            String organizationType = auditDetail.getOrganizationType();
            String roleId = auditDetail.getRoleId();
            if (Objects.isNull(detailMap.get(organizationType + roleId))) {
                detailMap.put(organizationType + roleId, auditDetail);
            }
            if (null == lastAudit || auditDetail.getAuditSequence() > lastAudit.getAuditSequence()) {
                lastAudit = auditDetail;
            }
        }
        // 记录当前审批节点
        AuditSettingDetail currentAudit = null;
        for (String roleCode : roleCodes) {
            AuditSettingDetail auditSettingDetail = detailMap.get(OrganizationType + roleSDOMap.get(roleCode));
            if (!Objects.isNull(auditSettingDetail)) {
                currentAudit = auditSettingDetail;
            }
        }
        if (Objects.isNull(currentAudit)) {
            log.error("AuditSettingDetailService.checkReportSetting.当前提报人未配置审批节点：{}", JSONObject.toJSONString(audit));
            throw new FacadeException(ErrorMessage.code("OTS-02-002-01-16-026"));
        }
        // 目前最后一个审批节点的角色不用提交审批，先兼容
        if (currentAudit.getId().equals(lastAudit.getId())) {
            stringBuilder.append("当前审批节点已经是最后一个，无需提交");
            return stringBuilder.toString();
        }
        //记录当前审批节点的下一个节点
        AuditSettingDetail firstAudit = currentAudit;
        List<AuditSettingDetail> list = auditDetails.stream().filter(detail -> {
            return detail.getAuditSequence() == firstAudit.getAuditSequence() + 1;
        }).collect(Collectors.toList());
        AuditSettingDetail nextAudit = list.get(0);
        // 记录后续审批节点
        Map</*id*/String, /*name*/String> roleSDOMap1 = getRoleSDOMap();
        List<String> subsequentAudit = auditDetails.stream().filter(detail -> !Objects.isNull(detail) && nextAudit.getAuditSequence() < detail.getAuditSequence())
                .map(detail -> roleSDOMap1.get(detail.getRoleId())).collect(Collectors.toList());
        stringBuilder.append("您将提交至").append(roleSDOMap1.get(nextAudit.getRoleId())).append("审批");
        if (CollectionUtils.isNotEmpty(subsequentAudit)) {
            stringBuilder.append("，后续需");
            boolean flag = false;
            for (String roleName : subsequentAudit) {
                if (flag) {
                    stringBuilder.append("、");
                } else {
                    flag = true;
                }
                stringBuilder.append(roleName);
            }
            stringBuilder.append("审批");
        }
        stringBuilder.append("。");
        log.error("AuditSettingDetailService.checkReportSetting.stringBuilder={}", stringBuilder.toString());
        return stringBuilder.toString();
    }

    private List<AuditSettingDetail> obtainAuditSettingDetail(AuditSetting request) {
        Result<List<AuditSettingDetail>> result = loadList(buildAuditSettingDetailRequest(request));
        if (!result.isSuccess() || org.apache.commons.collections.CollectionUtils.isEmpty(result.getResult())) {
            return Lists.newArrayList();
        }
        return result.getResult();
    }

    private AuditSettingDetailLoadListRequest buildAuditSettingDetailRequest(AuditSetting request) {
        AuditSettingDetailLoadListRequest detailRequest = new AuditSettingDetailLoadListRequest();
        detailRequest.setAuditSettingId(request.getId());
        detailRequest.setStatus(AuditSettingStatusEnum.ENABLE.getType());
        return detailRequest;
    }

    private List<AuditSetting> getAuditConfiguration(Integer organizationType, String organizationId, Integer model) {
        SalesPlanReportRequest salesPlanRequest = new SalesPlanReportRequest();
        salesPlanRequest.setModel(model);
        // 当前为销售渠道，或销售单元可直接获取对应审批配置
        if (OrganizationTypeEnum.SALES_CHANNEL.getCode().equals(organizationType)) {
            salesPlanRequest.setRelationOrganizationId(organizationId);
            salesPlanRequest.setRelationOrganizationType(OrganizationTypeEnum.SALES_CHANNEL.getCode());
        } else if (OrganizationTypeEnum.COMPANY.getCode().equals(organizationType)) {
            salesPlanRequest.setRelationOrganizationId(organizationId);
            salesPlanRequest.setRelationOrganizationType(OrganizationTypeEnum.COMPANY.getCode());
        } else if (OrganizationTypeEnum.SALES_DEPARTMENT.getCode().equals(organizationType)) {
            // 向上反查对应组织id
            com.epoch.app.crplatformenhance.sdo.OrganizationSDO organizationSDO = obtainUpOrganization(organizationId, OrganizationTypeEnum.SALES_CHANNEL.getCode());
            salesPlanRequest.setRelationOrganizationId(organizationSDO.getId());
            salesPlanRequest.setRelationOrganizationType(OrganizationTypeEnum.SALES_CHANNEL.getCode());
        } else if (OrganizationTypeEnum.SALES_ORGANIZATION.getCode().equals(organizationType)) {
            // 向上反查对应组织id
            com.epoch.app.crplatformenhance.sdo.OrganizationSDO organizationSDO = obtainUpOrganization(organizationId, OrganizationTypeEnum.COMPANY.getCode());
            salesPlanRequest.setRelationOrganizationId(organizationSDO.getId());
            salesPlanRequest.setRelationOrganizationType(OrganizationTypeEnum.COMPANY.getCode());
        } else  {
            throw new FacadeException(ErrorMessage.code("OTS-02-002-01-16-024"));
        }
        log.info("AuditSettingDetailService.obtainAuditSetting.request={}", JSONObject.toJSONString(salesPlanRequest));
        List<AuditSetting> auditSettings = obtainAuditSetting(salesPlanRequest);
        if (org.apache.commons.collections.CollectionUtils.isEmpty(auditSettings)) {
            throw new FacadeException(ErrorMessage.code("OTS-02-002-01-16-023"));
        }
        log.info("AuditSettingDetailService.obtainAuditSetting.auditSettings={}", JSONObject.toJSONString(auditSettings));
        return auditSettings;
    }

    /**
     * 获取当前审批人的上级组织
     * @return
     */
    private com.epoch.app.crplatformenhance.sdo.OrganizationSDO obtainUpOrganization(String relationOrganizationId, Integer upOrganizationType) {
        // 获取当前组织向上回溯指定类型组织列表
        List<com.epoch.app.crplatformenhance.sdo.OrganizationSDO> organizationSDOList = platformEnhanceRepository.getTopOrganizationList(convert(relationOrganizationId, upOrganizationType));
        if (org.apache.commons.collections.CollectionUtils.isEmpty(organizationSDOList)) {
            throw new FacadeException(ErrorMessage.code("OTS-02-003-01-16-013"));
        }
        // 获取最后一个组织即可
        return organizationSDOList.get(organizationSDOList.size() - 1);
    }

    private OrganizationListQueryRequest convert(String organizationId, Integer bizType) {
        OrganizationListQueryRequest topOrganizationListRequest = new OrganizationListQueryRequest();
        topOrganizationListRequest.setId(organizationId);
        topOrganizationListRequest.setType(bizType);
        return topOrganizationListRequest;
    }

    /**
     * 获取审批配置主单信息
     * @param request request
     * @return result
     */
    private List<AuditSetting> obtainAuditSetting(SalesPlanReportRequest request) {
        // 获取审批配置主单、可能有多个
        Result<List<AuditSetting>> result = auditSettingService.loadList(buildAuditSettingRequest(request));
        if (!result.isSuccess() || org.apache.commons.collections.CollectionUtils.isEmpty(result.getResult())) {
            return Lists.newArrayList();
        }
        return result.getResult();
    }

    private AuditSettingLoadListRequest buildAuditSettingRequest(SalesPlanReportRequest request) {
        AuditSettingLoadListRequest auditSettingRequest = new AuditSettingLoadListRequest();
        auditSettingRequest.setStatus(AuditSettingStatusEnum.ENABLE.getType());
        if (SalesPlanModelEnum.PLAN_MODEL.getModel().equals(request.getModel())) {
            auditSettingRequest.setType(AuditSettingTypeEnum.SALES_PLAN_REPORT.getType());
        } else if (SalesPlanModelEnum.ADJUST_MODEL.getModel().equals(request.getModel())) {
            auditSettingRequest.setType(AuditSettingTypeEnum.SALES_PLAN_ADJUST.getType());
        }
        if (OrganizationTypeEnum.SALES_DEPARTMENT.getCode().equals(request.getRelationOrganizationType()) ||
                OrganizationTypeEnum.SALES_CHANNEL.getCode().equals(request.getRelationOrganizationType())) {
            auditSettingRequest.setOrgChannelCode(request.getRelationOrganizationId());
        } else if (OrganizationTypeEnum.SALES_ORGANIZATION.getCode().equals(request.getRelationOrganizationType()) ||
                OrganizationTypeEnum.COMPANY.getCode().equals(request.getRelationOrganizationType())) {
            auditSettingRequest.setOrgBusinessUnitCode(request.getRelationOrganizationId());
        }
        log.info("SalesPlanReportWriteService.buildAuditSettingRequest.request={}", JSONObject.toJSONString(auditSettingRequest));
        return auditSettingRequest;
    }
}
